﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Coffee;
using Nop.Services.Coffee;
using Nop.Admin.Models.Coffee;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Security;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Telerik.Web.Mvc;

namespace Nop.Admin.Controllers
{
    [AdminAuthorize]
    public partial class CoffeeController : BaseNopController
    {
        #region Fields

        private readonly ILanguageService _languageService;
        private readonly IDateTimeHelper _dateTimeHelper;
        private readonly ILocalizationService _localizationService;
        private readonly IPermissionService _permissionService;
        private readonly AdminAreaSettings _adminAreaSettings;
        private readonly ICoffeeService _coffeeService;

        #endregion

        #region Constructors

        public CoffeeController(ILanguageService languageService,
            IDateTimeHelper dateTimeHelper, ILocalizationService localizationService,
            IPermissionService permissionService,
            AdminAreaSettings adminAreaSettings, ICoffeeService coffeeService)
        {
            this._languageService = languageService;
            this._dateTimeHelper = dateTimeHelper;
            this._localizationService = localizationService;
            this._permissionService = permissionService;
            this._adminAreaSettings = adminAreaSettings;
            this._coffeeService = coffeeService;
        }

        #endregion


        #region Beans

        public ActionResult Index()
        {
            return RedirectToAction("List");
        }

        public ActionResult BeanList()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel))
                return AccessDeniedView();

            var beans = _coffeeService.GetAllBeans();
            var gridModel = new GridModel<BeanModel>
            {
                Data = beans.Select(x => x.ToModel()),
                Total = beans.Count
            };
            return View(gridModel);
        }

        [HttpPost]
        public ActionResult BeanDelete(int Id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var bean = _coffeeService.GetBeanById(Id);
            if (bean == null)
                //No bean found with the specified id
                return RedirectToAction("BeanList");

            _coffeeService.DeactivateBean(bean);

            SuccessNotification("The bean was deleted");
            return RedirectToAction("BeanList");
        }

        public ActionResult BeanEdit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var bean = _coffeeService.GetBeanById(id);
            if (bean == null)
                //No bean found with the specified id
                return RedirectToAction("BeanList");

            var model = bean.ToModel();

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult BeanEdit(BeanModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var bean = _coffeeService.GetBeanById(model.Id);
            if (bean == null)
                //No topic found with the specified id
                return RedirectToAction("BeanList");

            if (ModelState.IsValid)
            {
                bean = model.ToEntity(bean);
                _coffeeService.UpdateBean(bean);

                SuccessNotification("The bean has been updated");
                return continueEditing ? RedirectToAction("BeanEdit", bean.Id) : RedirectToAction("BeanList");
            }


            //If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult BeanCreate()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var model = new BeanModel();
            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult BeanCreate(BeanModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            if (ModelState.IsValid)
            {
                var bean = model.ToEntity();
                _coffeeService.InsertBean(bean);

                return continueEditing ? RedirectToAction("BeanEdit", new { id = bean.Id }) : RedirectToAction("BeanList");
            }

            return View(model);
        }

        #endregion

        #region Blends

        public ActionResult BlendList()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel))
                return AccessDeniedView();

            var blendModels = PrepareBlendModel();

            var gridModel = new GridModel<BlendModel>
            {
                Data = blendModels,
                Total = blendModels.Count()
            };

            return View(gridModel);

        }

        [HttpPost]
        public ActionResult BlendDelete(int Id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var blend = _coffeeService.GetBlendById(Id);
            if (blend == null)
                //No bean found with the specified id
                return RedirectToAction("BlendList");

            _coffeeService.DeactivateBlend(blend);

            SuccessNotification("The bean was deleted");
            return RedirectToAction("BlendList");
        }

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult BlendBeanByBlendIdList(GridCommand command, int blendId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var blendBeans = _coffeeService.GetAllBlendBeansByBlendId(blendId);
            var blendBeanModel = new List<BlendModel.BlendBeanModel>();
            if (blendBeans.Count > 0)
            {
                blendBeanModel = blendBeans
                    .Select(x =>
                    {
                        var bbModel = new BlendModel.BlendBeanModel()
                        {
                            Id = x.Id,
                            BlendId = x.BlendId,
                            BeanId = x.BeanId,
                            BeanPercent = x.BeanPercent,
                            Blend = x.Blend.ToModel(),
                            Bean = x.Bean.ToModel()

                        };
                        return bbModel;
                    })
                    .ToList();
            }
            var model = new GridModel<BlendModel.BlendBeanModel>
            {
                Data = blendBeanModel,
                Total = blendBeanModel.Count
            };

            return new JsonResult
            {
                Data = model
            };
        }

        [NonAction]
        protected BlendModel PrepareBlendModelForEdit(int id)
        {

            var blend = _coffeeService.GetBlendById(id);
            var availableBeans = _coffeeService.GetAllBeansNotInBlend(id)
                .Select(b =>
                  new SelectListItem
                  {
                      Text = b.Name,
                      Value = b.Id.ToString()
                  }).ToList();

            var model = new BlendModel()
            {
                Id = blend.Id,
                Name = blend.Name,
                Description = blend.Description,
                IsActive = blend.IsActive,
                AvailableBeans = availableBeans,
            };

            var blendBeans = _coffeeService.GetAllBlendBeansByBlendId(blend.Id);

            foreach (var blendBean in blendBeans)
            {
                model.BlendBeans.Add(new BlendModel.BlendBeanModel()
                {
                    Id = blendBean.Id,
                    BeanId = blendBean.BeanId,
                    BlendId = blendBean.BlendId,
                    BeanPercent = blendBean.BeanPercent,
                    Bean = _coffeeService.GetBeanById(blendBean.BeanId).ToModel(),
                    Blend = _coffeeService.GetBlendById(blendBean.BlendId).ToModel()

                });
            }

            return model;
        }

        [NonAction]
        protected IEnumerable<BlendModel> PrepareBlendModel()
        {

            List<BlendModel> models = new List<BlendModel>();
            var blends = _coffeeService.GetAllBlends();
            var recipes = _coffeeService.GetAllRecipes();

            foreach (var blend in blends)
            {

                var blendBeans = _coffeeService.GetAllBlendBeansByBlendId(blend.Id);
                var recipeBlends = _coffeeService.GetAllRecipeBlendsByBlendId(blend.Id);


                var model = new BlendModel()
                {
                    Id = blend.Id,
                    Name = blend.Name,
                    Description = blend.Description,
                    IsActive = blend.IsActive
                };

                foreach (var blendBean in blendBeans)
                {
                    model.BlendBeans.Add(new BlendModel.BlendBeanModel()
                    {
                        BeanId = blendBean.BeanId,
                        BlendId = blendBean.BlendId,
                        BeanPercent = blendBean.BeanPercent,
                        Bean = _coffeeService.GetBeanById(blendBean.Id).ToModel(),
                        Blend = _coffeeService.GetBlendById(blendBean.Id).ToModel()
                    });
                }

                models.Add(model);

            }

            return models;

        }


        public ActionResult BlendEdit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var blend = _coffeeService.GetBlendById(id);
            if (blend == null)
                //No bean found with the specified id
                return RedirectToAction("BlendList");

            var model = PrepareBlendModelForEdit(id);

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult BlendEdit(BlendModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var blend = _coffeeService.GetBlendById(model.Id);
            if (blend == null)
                //No topic found with the specified id
                return RedirectToAction("BlendList");

            if (ModelState.IsValid)
            {
                blend = model.ToEntity(blend);
                _coffeeService.UpdateBlend(blend);

                SuccessNotification("The blend has been updated");
                return continueEditing ? RedirectToAction("BlendEdit", blend.Id) : RedirectToAction("BlendList");
            }


            //If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult BlendCreate()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var model = new BlendModel();
            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult BlendCreate(BlendModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            if (ModelState.IsValid)
            {
                var blend = model.ToEntity();
                _coffeeService.InsertBlend(blend);

                return continueEditing ? RedirectToAction("BlendEdit", new { id = blend.Id }) : RedirectToAction("BlendList");
            }

            return View(model);
        }

        #endregion

        #region Recipes

        public ActionResult RecipeList()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel))
                return AccessDeniedView();

            var recipes = _coffeeService.GetAllRecipes();
            var gridModel = new GridModel<RecipeModel>
            {
                Data = recipes.Select(x => x.ToModel()),
                Total = recipes.Count
            };
            return View(gridModel);
        }

        [HttpPost]
        public ActionResult RecipeDelete(int Id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var recipe = _coffeeService.GetRecipeById(Id);
            if (recipe == null)
                //No bean found with the specified id
                return RedirectToAction("RecipeList");

            _coffeeService.DeactivateRecipe(recipe);

            SuccessNotification("The recipe was deleted");
            return RedirectToAction("RecipeList");
        }

        public ActionResult RecipeEdit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var recipe = _coffeeService.GetRecipeById(id);
            if (recipe == null)
                //No bean found with the specified id
                return RedirectToAction("RecipeList");

            var model = PrepareRecipeModelForEdit(id);

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult RecipeEdit(RecipeModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var recipe = _coffeeService.GetRecipeById(model.Id);
            if (recipe == null)
                //No topic found with the specified id
                return RedirectToAction("RecipeList");

            if (ModelState.IsValid)
            {
                recipe = model.ToEntity(recipe);
                _coffeeService.UpdateRecipe(recipe);

                SuccessNotification("The recipe has been updated");
                return continueEditing ? RedirectToAction("RecipeEdit", recipe.Id) : RedirectToAction("RecipeList");
            }


            //If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult RecipeCreate()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            var model = new RecipeModel();
            return View(model);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult RecipeCreate(RecipeModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTopics))
                return AccessDeniedView();

            if (ModelState.IsValid)
            {
                var recipe = model.ToEntity();
                _coffeeService.InsertRecipe(recipe);

                return continueEditing ? RedirectToAction("RecipeEdit", new { id = recipe.Id }) : RedirectToAction("RecipeList");
            }

            return View(model);
        }

        [NonAction]
        protected RecipeModel PrepareRecipeModelForEdit(int id)
        {

            var recipe = _coffeeService.GetRecipeById(id);
            var availableBlends = _coffeeService.GetAllBlendsNotInRecipe(id)
                .Select(b =>
                  new SelectListItem
                  {
                      Text = b.Name,
                      Value = b.Id.ToString()
                  }).ToList();

            var model = new RecipeModel()
            {
                Id = recipe.Id,
                Name = recipe.Name,
                IsActive = recipe.IsActive,
                AvailableBlends = availableBlends
            };

            var recipeBlends = _coffeeService.GetAllRecipeBlendsByRecipeId(recipe.Id);

            foreach (var recipeBlend in recipeBlends)
            {
                model.RecipeBlends.Add(new RecipeModel.RecipeBlendModel()
                {
                    Id = recipeBlend.Id,
                    RecipeId = recipeBlend.RecipeId,
                    BlendId = recipeBlend.BlendId,
                    FinishTemperature = recipeBlend.FinishTemperature,
                    Notes = recipeBlend.Notes,
                    PercentOfRecipe = recipeBlend.PercentOfRecipe,
                    Recipe = _coffeeService.GetRecipeById(recipeBlend.RecipeId).ToModel(),
                    Blend = _coffeeService.GetBlendById(recipeBlend.BlendId).ToModel()

                });
            }

            return model;
        }

        #endregion

        #region BlendBeans

        public ActionResult BlendBeanAdd(int blendId, int beanId, int beanPercent)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var bb = new BlendBean()
            {
                BlendId = blendId,
                BeanId = beanId,
                BeanPercent = beanPercent,
                Bean = _coffeeService.GetBeanById(beanId),
                Blend = _coffeeService.GetBlendById(blendId)
            };

            _coffeeService.InsertBlendBean(bb);

            return Json(new { Result = true }, JsonRequestBehavior.AllowGet);
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult BlendBeanUpdate(BlendModel.BlendBeanModel model, GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var blendBean = _coffeeService.GetBlendBeanById(model.Id);
            if (blendBean == null)
                throw new ArgumentException("No blend bean found with the specified id");

            blendBean.BeanPercent = model.BeanPercent;
            _coffeeService.UpdateBlendBean(blendBean);

            return BlendBeanByBlendIdList(command, blendBean.BlendId);
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult BlendBeanDelete(int id, GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var blendBean = _coffeeService.GetBlendBeanById(id);
            var blendId = blendBean.BlendId;
            if (blendBean == null)
                throw new ArgumentException("No blend bean found with the specified id");

            _coffeeService.DeleteBlendBean(blendBean);

            return BlendBeanByBlendIdList(command, blendId);
        }

        #endregion

        #region RecipeBlends

        public ActionResult RecipeBlendAdd(int recipeId, int blendId, int finishTemp, string Notes, int percent)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var rb = new RecipeBlend()
            {
                RecipeId = recipeId,
                BlendId = blendId,
                FinishTemperature = finishTemp,
                Notes = Notes,
                PercentOfRecipe = percent,
                Recipe = _coffeeService.GetRecipeById(recipeId),
                Blend = _coffeeService.GetBlendById(blendId)
            };

            _coffeeService.InsertRecipeBlend(rb);

            return Json(new { Result = true }, JsonRequestBehavior.AllowGet);
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult RecipeBlendUpdate(RecipeModel.RecipeBlendModel model, GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var recipeBlend = _coffeeService.GetRecipeBlendById(model.Id);
            if (recipeBlend == null)
                throw new ArgumentException("No recipe blend found with the specified id");

            recipeBlend.FinishTemperature = model.FinishTemperature;
            recipeBlend.PercentOfRecipe = model.PercentOfRecipe;
            recipeBlend.Notes = model.Notes;

            _coffeeService.UpdateRecipeBlend(recipeBlend);

            return RecipeBlendByRecipeIdList(command, recipeBlend.RecipeId);
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult RecipeBlendDelete(int id, GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var recipeBlend = _coffeeService.GetRecipeBlendById(id);
            var recipeId = recipeBlend.RecipeId;
            if (recipeBlend == null)
                throw new ArgumentException("No recipe blend found with the specified id");

            _coffeeService.DeleteRecipeBlend(recipeBlend);

            return RecipeBlendByRecipeIdList(command, recipeId);
        }

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult RecipeBlendByRecipeIdList(GridCommand command, int recipeId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return AccessDeniedView();

            var recipeBlends = _coffeeService.GetAllRecipeBlendsByRecipeId(recipeId);
            var recipeBlendModel = recipeBlends
                .Select(x =>
                {
                    var rbModel = new RecipeModel.RecipeBlendModel()
                    {
                        Id = x.Id,
                        RecipeId = x.RecipeId,
                        BlendId = x.BlendId,
                        FinishTemperature = x.FinishTemperature,
                        Notes = x.Notes,
                        PercentOfRecipe = x.PercentOfRecipe,
                        Recipe = x.Recipe.ToModel(),
                        Blend = x.Blend.ToModel()

                    };
                    return rbModel;
                })
                .ToList();

            var model = new GridModel<RecipeModel.RecipeBlendModel>
            {
                Data = recipeBlendModel,
                Total = recipeBlendModel.Count
            };

            return new JsonResult
            {
                Data = model
            };
        }

       

        #endregion


    }
}
